home *** CD-ROM | disk | FTP | other *** search
/ Aminet 52 / Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso / Aminet / gfx / misc / VLab_pss.lha / VLab_PSS / Sources / VLab.c < prev   
C/C++ Source or Header  |  2002-10-27  |  46KB  |  1,330 lines

  1. /*
  2. **  VLab plug-in for ArtEffect
  3. **  © 2002 Kakace Productions
  4. **
  5. */
  6.  
  7.  
  8. #define PLUGIN_VERSION  "VLab.pss 1.8 (27.10.2002)"
  9.  
  10.  
  11. #include <stdlib.h>
  12.  
  13. #ifndef  INTUITION_INTUITION_H
  14. #include <intuition/intuition.h>
  15. #endif
  16.  
  17. #ifndef  UTILITY_TAGITEM_H
  18. #include <utility/tagitem.h>
  19. #endif
  20.  
  21. #ifndef  ARTEFFECT_AE_PLUGIN_H
  22. #include <libraries/ae_plugin.h>
  23. #endif
  24.  
  25. #ifndef  MONITOR_H
  26. #include "Monitor.h"
  27. #endif
  28.  
  29. #ifndef  VLAB_CONFIG_H
  30. #include "VLab_Config.h"
  31. #endif
  32.  
  33. #include <proto/exec.h>
  34. #include <proto/ae_plugin.h>
  35.  
  36.  
  37. #define COPYRIGHT  PLUGIN_VERSION" © 2002, Kakace Productions.\0$VER: "PLUGIN_VERSION"\r\n"
  38.  
  39.  
  40. /*------------------------------------------------------------------------------------------------*/
  41.  
  42. AE_DialogPtr PlugIn_OpenWindow(AE_AppObjPtr app);
  43. void         PlugIn_CloseWindow(AE_AppObjPtr app, AE_DialogPtr window);
  44. void         PlugIn_Apply(AE_AppObjPtr app, AE_EventPtr event);
  45.  
  46. struct VLabMonitor *PlugIn_HandleGadget(AE_AppObjPtr app, AE_DialogPtr window, AE_EventPtr event,
  47.                                         struct VLabMonitor *monitoring);
  48.  
  49. static void showError(AE_AppObjPtr app, ULONG errorID);
  50. static void closeMonitor(struct VLabSettings *settings, struct VLabMonitor *monitor);
  51. static void updateGadgets(AE_AppObjPtr app, AE_DialogPtr window, struct InputSettings *inputCfg);
  52.  
  53.  
  54. /*
  55. ** Error codes and error strings for showError()
  56. */
  57.  
  58. enum PlugIn_ErrorID {
  59.     ERROR_NONE,
  60.     ERROR_NO_MEMORY,
  61.     ERROR_NO_WINDOW,
  62.     ERROR_VLAB_BUSY
  63. };
  64.  
  65. static const char *PlugIn_Errors[] = {
  66.     "Not enough memory.",
  67.     "Unable to open the window.",
  68.     "The VLab is currently busy."
  69. };
  70.  
  71.  
  72. /*------------------------------------------------------------------------------------------------*/
  73.  
  74. /*
  75. ** Default settings
  76. */
  77.  
  78. static const struct VLabSettings DefSettings = {DEFAULT_CONF};
  79.  
  80.  
  81. /*
  82. ** Global datas
  83. */
  84.  
  85. static struct VLabSettings SavedSettings;   /* Loaded upon startup by ArtEffect */
  86. static struct VLabSettings CurSettings;     /* Current settings */
  87. static ULONG  MaxInputs;                    /* Max number of inputs. 2 = VLab Classic, 3 = VLab Y/C */
  88. static UBYTE *RGB_Buffer;                   /* Allocated at startup time */
  89.  
  90. struct Library *AEPlugInBase;
  91.  
  92.  
  93. /*
  94. ** Private functions
  95. */
  96.  
  97. static void                handleEvents(AE_AppObjPtr application, AE_DialogPtr window);
  98. static void                set_monitoring_flags(struct VLabSettings *settings);
  99. static struct VLabMonitor *open_monitor(AE_AppObjPtr app, AE_EventPtr event, struct VLabSettings *settings);
  100.  
  101.  
  102. /*
  103. ** We cannot change all flags when the monitor is running.
  104. ** The mask below must be applied to filter flags changes in this case.
  105. */
  106.  
  107. #define MONITORING_MASK ~(VLABF_LACE | VLABF_HIRES)
  108.  
  109.  
  110. /*------------------------------------------------------------------------------------------------*/
  111.  
  112.  
  113. int main(int argc, char *argv[])
  114. {
  115.     static struct TagItem tags[] = {
  116.         {PLUGIN_INFO_NAME, (ULONG) "VLab"},
  117.         {PLUGIN_INFO_COPYRIGHT, (ULONG) COPYRIGHT},
  118.         {PLUGIN_INFO_MENUTITLE, (ULONG) "VLab..."},
  119.         {PLUGIN_INFO_CONFIG, (ULONG) &SavedSettings},
  120.         {TAG_DONE}
  121.     };
  122.  
  123.     int  ret = EXIT_FAILURE;
  124.  
  125.     if ( (AEPlugInBase = OpenLibrary("ArtEffect:libs/ae_plugin.library", 2)) ) {
  126.  
  127.         struct TagItem *tagList;            /* Initialization tag list  */
  128.         AE_AppObjPtr    app;                /* Application object       */
  129.         LONG            plugInType;         /* Plug-in type             */
  130.  
  131.         /*
  132.         ** Initialize our plug-in
  133.         */
  134.  
  135.         SavedSettings = DefSettings;
  136.         plugInType = PLUGIN_TYPE_ERROR;
  137.         tagList = NULL;
  138.  
  139.         if ( (MaxInputs = VLab_IdentifyHardware()) ) {
  140.             plugInType = PLUGIN_TYPE_SCANNER;
  141.             tagList = tags;
  142.         }
  143.  
  144.         /*
  145.         ** Event handling
  146.         */
  147.  
  148.         if ( (app = AE_SetupPlugInTagList(argc, argv, plugInType, tagList)) ) {
  149.             struct Task *task;
  150.             AE_DialogPtr window;
  151.             LONG         oldPri;
  152.             enum PlugIn_ErrorID errcode = ERROR_NO_MEMORY;
  153.  
  154.             task   = FindTask(NULL);
  155.             oldPri = SetTaskPri(task, 0);
  156.  
  157.             /*
  158.             ** Allocate the YUV and RGB buffers now so that we won't have to deal with
  159.             ** this if the user decide to digitize several picture before closing the
  160.             ** window.
  161.             */
  162.  
  163.             if (VLab_AllocateYUV()) {
  164.                 if ( (RGB_Buffer = (UBYTE *) AllocVec(VLAB_MAXWIDTH * VLAB_MAXHEIGHT_PAL * 3, MEMF_ANY)) ) {
  165.  
  166.                     errcode = ERROR_VLAB_BUSY;
  167.  
  168.                     if (VLab_OwnHardware()) {
  169.  
  170.                         errcode = ERROR_NO_WINDOW;
  171.                         InitMonitoring();               /* Must be called before opening the main window */
  172.                         CurSettings = SavedSettings;
  173.  
  174.                         if ( (window = PlugIn_OpenWindow(app)) ) {
  175.                             handleEvents(app, window);
  176.                             SavedSettings = CurSettings;
  177.                             PlugIn_CloseWindow(app, window);
  178.                             errcode = ERROR_NONE;
  179.                         }
  180.  
  181.                         CleanupMonitoring();
  182.                         VLab_FreeHardware();
  183.                     }
  184.                     FreeVec(RGB_Buffer);
  185.                 }
  186.                 VLab_FreeYUV();
  187.             }
  188.  
  189.             showError(app, errcode);
  190.             AE_ExitPlugIn(app);
  191.  
  192.             SetTaskPri(task, oldPri);
  193.         }
  194.  
  195.         CloseLibrary(AEPlugInBase);
  196.         ret = EXIT_SUCCESS;
  197.     }
  198.  
  199.     return ret;
  200. }
  201.  
  202.  
  203. static void handleEvents(AE_AppObjPtr app, AE_DialogPtr window)
  204. {
  205.     struct VLabSettings *settings;
  206.     struct VLabMonitor *monitoring;
  207.     ULONG  monitorBitMask = 0;      /* Signal mask (monitoring)  */
  208.     ULONG  appBitMask;              /* Signal mask (main window) */
  209.     int    running = TRUE;
  210.     AE_EventPtr event;
  211.  
  212.     settings = &CurSettings;
  213.     monitoring = NULL;
  214.  
  215.     appBitMask = 1 << app->UserPort->mp_SigBit;
  216.  
  217.     do {
  218.         int signals = 0;
  219.  
  220.         /*
  221.         ** If the monitoring is active, we poll the signals
  222.         ** continuously. Otherwise, we wait for an event
  223.         ** from ArtEffect.
  224.         */
  225.  
  226.         if (monitoring) {
  227.             UpdateMonitorWindow(monitoring);
  228.             monitorBitMask = 1 << MonitoringWindow(monitoring)->UserPort->mp_SigBit;
  229.             signals = SetSignal(0, 0);
  230.         }
  231.         else {
  232.             monitorBitMask = 0;
  233.             WaitPort(app->UserPort);
  234.             signals = appBitMask;
  235.         }
  236.  
  237.         /*
  238.         ** Handle monitoring window's IDCMP
  239.         */
  240.  
  241.         if (signals & monitorBitMask) {
  242.             struct IntuiMessage *imsg;
  243.             int close = FALSE;
  244.  
  245.             SetSignal(0, signals & monitorBitMask);
  246.  
  247.             while( (imsg = (struct IntuiMessage *) GetMsg(MonitoringWindow(monitoring)->UserPort)) ){
  248.  
  249.                 if (imsg->Class == IDCMP_CLOSEWINDOW)
  250.                     close = TRUE;
  251.  
  252.                 ReplyMsg((struct Message *) imsg);
  253.             }
  254.  
  255.             if (close) {
  256.                 closeMonitor(settings, monitoring);
  257.                 monitoring = NULL;
  258.             }
  259.         }
  260.  
  261.         /*
  262.         ** Handle plug-in window's messages.
  263.         */
  264.  
  265.         if (signals & appBitMask) {
  266.             SetSignal(0, signals & appBitMask);
  267.  
  268.             while ( (event = AE_GetEvent(app)) ) {
  269.  
  270.                 switch (event->Type) {
  271.  
  272.                     case PLUGIN_EVENT_GADGET:
  273.                         monitoring = PlugIn_HandleGadget(app, window, event, monitoring);
  274.                         break;
  275.  
  276.  
  277.                     case PLUGIN_EVENT_EXECUTE:
  278.                         PlugIn_Apply(app, event);
  279.                         /*
  280.                         ** Reset monitoring flags.
  281.                         */
  282.                         if (monitoring)
  283.                             set_monitoring_flags(settings);
  284.  
  285.                         break;
  286.  
  287.  
  288.                     case PLUGIN_EVENT_QUIT:
  289.                         running = FALSE;
  290.  
  291.                         if (monitoring) {
  292.                             closeMonitor(settings, monitoring);
  293.                             monitoring = NULL;
  294.                         }
  295.                         break;
  296.  
  297.                 }
  298.                 AE_ReplyEvent(app, event);
  299.             }
  300.         }
  301.     } while (running);
  302. }
  303.  
  304.  
  305. static void closeMonitor(struct VLabSettings *settings, struct VLabMonitor *monitor)
  306. {
  307.     settings->vs_WLeft = MonitoringWindow(monitor)->LeftEdge;
  308.     settings->vs_WTop  = MonitoringWindow(monitor)->TopEdge;
  309.     CloseMonitorWindow(monitor);
  310. }
  311.  
  312.  
  313. static void showError(AE_AppObjPtr app, ULONG errorID)
  314. {
  315.     if (errorID--) {
  316.         AE_DoRequestTags(app, AER_TYPE_INFO, AER_BodyText, (ULONG) PlugIn_Errors[errorID],
  317.                 AER_TitleText, (ULONG) "VLab error", TAG_DONE);
  318.     }
  319. }
  320.  
  321.  
  322. /*------------------------------------------------------------------------------------------------*/
  323.  
  324. /****** VLab/PlugIn_OpenWindow **********************************************
  325. *
  326. *   NAME
  327. *   PlugIn_OpenWindow -- Open the dialog window
  328. *
  329. *   SYNOPSIS
  330. *   window = PlugIn_OpenWindow(app)
  331. *
  332. *   AE_DialogPtr PlugIn_OpenWindow(AE_AppObjPtr);
  333. *
  334. *   FUNCTION
  335. *   Open the dialog window. The window shall be closed by a call to the
  336. *   PlugIn_CloseWindow() function.
  337. *
  338. *   INPUTS
  339. *   app - Object pointer returned by AE_SetupPlugInTagList().
  340. *
  341. *   RESULT
  342. *   window - Pointer to the newly opened window, or NULL if an error occured
  343. *            or if no window is needed.
  344. *
  345. *   NOTES
  346. *   Gadgets related to the monitoring feature might be disabled if the
  347. *   monitoring is not available (depending on the screen mode and the
  348. *   availability of the PiP feature).
  349. *
  350. *   BUGS
  351. *
  352. *   SEE ALSO
  353. *   PlugIn_CloseWindow(), AE_OpenWindowTagList()
  354. *
  355. *****************************************************************************
  356. *
  357. */
  358.  
  359. /*
  360. ** Gadgets ID.
  361. ** Those ID depend upon the order in which each gadget appears in the tag list
  362. ** passed to AE_OpenWindowTags().
  363. ** We also use cycle gadgets instead of HRADIO because the latter are no longer
  364. ** supported by ArtEffect (all radio buttons are rendered verticaly).
  365. */
  366.  
  367. enum gadgetsID {
  368.         /* Video */
  369.         GADID_INPUT = 1,            /* Input selector (cycle gadget). 2 or 3 values. */
  370.         GADID_VIDEO,                /* Video mode (cycle gadget, 5 values)      */
  371.         GADID_HUE,                  /* Hue value (integer)                      */
  372.  
  373.         /* Filters */
  374.         GADID_VTR,                  /* VTR flag (checkbox)                      */
  375.         GADID_PREFILTER,            /* Prefilter flag (checkbox)                */
  376.         GADID_BW_SOURCE,            /* B&W source flag (checkbox)               */
  377.         GADID_BANDPASS,             /* Bandpass filter (cycle gadget), 4 values */
  378.         GADID_CORING,               /* Coring point (cycle gadget), 4 values    */
  379.         GADID_WEIGHT,               /* Filter weight (cycle gadget), 4 values   */
  380.  
  381.         /* Image */
  382.         GADID_HIRES,                /* HiRes flag (checkbox)                    */
  383.         GADID_LACE,                 /* Lace flag (checkbox)                     */
  384.         GADID_COLOR,                /* Greyscale flag (checkbox)                */
  385.  
  386.         GADID_GAMMA,                /* Gamma correction (luma)                  */
  387.         GADID_BRIGHT,               /* Brightness correction                    */
  388.         GADID_CONTRAST,             /* Contrast correction                      */
  389.         /* Clipping */
  390.         GADID_XPOS,                 /* X position (integer)                     */
  391.         GADID_YPOS,                 /* Y position (integer)                     */
  392.         GADID_WIDTH,                /* Width (integer)                          */
  393.         GADID_HEIGHT,               /* Height (integer)                         */
  394.         /* Monitoring */
  395.         GADID_DISABLE_PIP,          /* 1 = Disable PiP monitoring               */
  396.         GADID_COLORMONITOR,         /* 1 = Color monitoring                     */
  397.         GADID_RESOLUTION,           /* Resolution ID (cycle gadget, 4 values)   */
  398.         GADID_OPENMONITOR,          /* Open monitor window (button)             */
  399.  
  400.         GADID_RESET,                /* Reset configuration to last saved values */
  401. };
  402.  
  403.  
  404. AE_DialogPtr PlugIn_OpenWindow(AE_AppObjPtr app)
  405. {
  406.     static const char *VLAB_YC_InputNames[] = {"Input", "CVBS-1", "CVBS-2", "S-VHS (Y/C)", NULL};
  407.     static const char *VLAB_InputNames[]    = {"Input", "CVBS-1", "CVBS-2", NULL};
  408.     static const char *VLAB_Video[]         = {"Source", "PAL B/G/H/I", "PAL N", "PAL M", "NTSC 4.43", "NTSC M", NULL};
  409.     static const char *VLAB_Resolutions[]   = {"Preview", "Small", "Medium", "Large", NULL};
  410.     static const char *VLAB_Bandpass[]      = {"Bandpass", "4.1 MHz", "3.8 MHz", "2.6 MHz", "2.9 MHz", NULL};
  411.     static const char *VLAB_Coring[]        = {"Noise", "OFF", "Weak", "Medium", "Strong", NULL};
  412.     static const char *VLAB_Weight[]        = {"K factor", "OFF", "Weak", "Medium", "Strong", NULL};
  413.  
  414.     /*
  415.     ** The GUI has to be modified depending upon the availability of the monitoring
  416.     ** feature. The two tag lists below implement this.
  417.     */
  418.  
  419.     static const struct TagItem finalTags[] = {
  420.         {AE_Bar},
  421.         {AE_HGroup},
  422.         {PLUGIN_INFO_ID, GADID_RESET},
  423.         {PLUGIN_INFO_BUTTON, (ULONG) "Reset settings"},         /* GADGET */
  424.         {AE_Bar},
  425.         {PLUGIN_INFO_ACTION, (ULONG) "<< GRAB >>"},             /* GADGET */
  426.         {AE_EndGroup},
  427.         {PLUGIN_INFO_TITLE, (ULONG) "VLab settings..."},
  428.         {TAG_DONE}
  429.     };
  430.  
  431.     static struct TagItem monitoringTags[] = {                  /* INDEX    */
  432.         {AE_Title("Monitoring")},                               /*  0       */
  433.         {AE_HGroup},                                            /*  1       */
  434.         {AE_VGroup},                                            /*  2       */
  435.         {PLUGIN_INFO_ACTIVE, 0},                                /*  3 <==   */
  436.         {PLUGIN_INFO_CHECKBOX, (ULONG) "Disable PiP"},          /*  4 GDGT  */
  437.         {PLUGIN_INFO_ACTIVE, 0},                                /*  5 <==   */
  438.         {PLUGIN_INFO_CHECKBOX, (ULONG) "Color preview"},        /*  6 GDGT  */
  439.         {AE_EndGroup},                                          /*  7       */
  440.         {AE_VGroup},                                            /*  8       */
  441.         {PLUGIN_INFO_ACTIVE, 1},                                /*  9 <==   */
  442.         {PLUGIN_INFO_CYCLE, (ULONG) VLAB_Resolutions},          /* GADGET   */
  443.         {PLUGIN_INFO_BUTTON, (ULONG) "Start monitor"},          /* GADGET   */
  444.         {AE_EndGroup},
  445.         {AE_EndGroup},
  446.         {TAG_MORE, (ULONG) finalTags}
  447.     };
  448.  
  449.     struct VLabSettings *settings = &CurSettings;
  450.     struct InputSettings *inputCfg = &settings->vs_Settings[settings->vs_Input];
  451.     AE_DialogPtr window = NULL;
  452.     ULONG maxH, maxW, flags;
  453.  
  454.     flags = inputCfg->is_Flags;
  455.  
  456.     /*
  457.     ** Verify the settings. ArtEffect automaticaly loads the settings from a
  458.     ** configuration file, so we shall check the settings version and reload
  459.     ** the default settings when a mismatch occurs.
  460.     */
  461.  
  462.     if (settings->vs_CfgVer != CONFIG_VERSION)
  463.         CurSettings = SavedSettings = DefSettings;
  464.  
  465.     /*
  466.     ** Setup default monitoring values in the related taglist.
  467.     */
  468.  
  469.     monitoringTags[3].ti_Data = (settings->vs_MonFlags & MONITOR_NO_PIP) ? 1 : 0;
  470.     monitoringTags[5].ti_Data = (settings->vs_MonFlags & MONITOR_COLOR) ? 1 : 0;
  471.     monitoringTags[9].ti_Data = settings->vs_Resolution;
  472.  
  473.     /*
  474.     ** Inform the vlab about the default settings.
  475.     */
  476.  
  477.     VLab_ChangeInput(settings->vs_Input);
  478.     VLab_ChangeVideo(inputCfg->is_VideoStd);
  479.     VLab_ChangeHue(inputCfg->is_Hue);
  480.     VLab_ChangeFlags(flags);
  481.     VLab_LumaCorrection(inputCfg->is_Gamma, inputCfg->is_Brightness, inputCfg->is_Contrast);
  482.     VLab_ChangeFilters(inputCfg->is_Filters);
  483.  
  484.     maxH = VLab_FrameHeight(inputCfg->is_VideoStd, flags);
  485.     maxW = VLab_FrameWidth(flags);
  486.  
  487.     /*
  488.     ** Open the window.
  489.     ** We use AE_OpenWindowTags() because most tags shall be initialized properly and
  490.     ** because this allows us to modify the TagList without too much troubles.
  491.     **
  492.     ** The default "Execute" button is replaced by an ACTION button. I don't know
  493.     ** whether this is the right thing to do. Looks like it works though...
  494.     **
  495.     ** ArtEffect forget the window title when the tag appear near the top of the
  496.     ** tag list. I tried several things to figure out what happens, and I think it
  497.     ** has something to do with Groups.
  498.     */
  499.  
  500.     if (!app->Quiet) {
  501.         window = AE_OpenWindowTags(app,
  502.             PLUGIN_INFO_ACTIVE, settings->vs_Input,                 /* GADGET */
  503.             PLUGIN_INFO_CYCLE, (ULONG) (MaxInputs == 2 ? VLAB_InputNames : VLAB_YC_InputNames),
  504.             PLUGIN_INFO_ACTIVE, inputCfg->is_VideoStd,
  505.             PLUGIN_INFO_CYCLE, (ULONG) VLAB_Video,                  /* GADGET */
  506.             PLUGIN_INFO_VALUE_MIN, -180,
  507.             PLUGIN_INFO_VALUE_MAX, 180,
  508.             PLUGIN_INFO_VALUE_DEF, inputCfg->is_Hue,
  509.             PLUGIN_INFO_VALUE, (ULONG) "Hue (NTSC)",                /* GADGET */
  510.  
  511.             AE_Title("Luminance filters"),
  512.             AE_HGroup,
  513.             AE_VGroup,
  514.             PLUGIN_INFO_ACTIVE, (flags & VLABF_VTR ? 1 : 0),
  515.             PLUGIN_INFO_CHECKBOX, (ULONG) "VTR",                    /* GADGET */
  516.             PLUGIN_INFO_ACTIVE, (flags & VLABF_PREFILTER ? 0 : 1),
  517.             PLUGIN_INFO_CHECKBOX, (ULONG) "Pre-filter",             /* GADGET */
  518.             PLUGIN_INFO_ACTIVE, (flags & VLABF_BW_SOURCE ? 1 : 0),
  519.             PLUGIN_INFO_CHECKBOX, (ULONG) "B&W source",             /* GADGET */
  520.             AE_EndGroup,
  521.             AE_VGroup,
  522.             PLUGIN_INFO_ACTIVE, FILTER_BANDPASS_R(inputCfg->is_Filters),
  523.             PLUGIN_INFO_CYCLE, (ULONG) VLAB_Bandpass,               /* GADGET */
  524.             PLUGIN_INFO_ACTIVE, FILTER_CORING_R(inputCfg->is_Filters),
  525.             PLUGIN_INFO_CYCLE, (ULONG) VLAB_Coring,                 /* GADGET */
  526.             PLUGIN_INFO_ACTIVE, FILTER_FACTOR_R(inputCfg->is_Filters),
  527.             PLUGIN_INFO_CYCLE, (ULONG) VLAB_Weight,                 /* GADGET */
  528.             AE_EndGroup,
  529.             AE_EndGroup,
  530.  
  531.             AE_Title("Image"),
  532.             AE_HGroup,
  533.             AE_VGroup,
  534.             PLUGIN_INFO_ACTIVE, (flags & VLABF_HIRES ? 1 : 0),
  535.             PLUGIN_INFO_CHECKBOX, (ULONG) "HiRes",                  /* GADGET */
  536.             PLUGIN_INFO_ACTIVE, (flags & VLABF_LACE ? 1 : 0),
  537.             PLUGIN_INFO_CHECKBOX, (ULONG) "Lace",                   /* GADGET */
  538.             PLUGIN_INFO_ACTIVE, (flags & VLABF_COLOR ? 1 : 0),
  539.             PLUGIN_INFO_CHECKBOX, (ULONG) "Color",                  /* GADGET */
  540.             AE_EndGroup,
  541.             AE_VGroup,
  542.             PLUGIN_INFO_VALUE_MIN, VLAB_GAMMA_MIN,
  543.             PLUGIN_INFO_VALUE_MAX, VLAB_GAMMA_MAX,
  544.             PLUGIN_INFO_VALUE_DEF, inputCfg->is_Gamma,
  545.             PLUGIN_INFO_VALUE, (ULONG) "Gamma",                     /* GADGET */
  546.             PLUGIN_INFO_VALUE_MIN, VLAB_BRIGHT_MIN,
  547.             PLUGIN_INFO_VALUE_MAX, VLAB_BRIGHT_MAX,
  548.             PLUGIN_INFO_VALUE_DEF, inputCfg->is_Brightness,
  549.             PLUGIN_INFO_VALUE, (ULONG) "Brightness",                /* GADGET */
  550.             PLUGIN_INFO_VALUE_MIN, VLAB_CONTRAST_MIN,
  551.             PLUGIN_INFO_VALUE_MAX, VLAB_CONTRAST_MAX,
  552.             PLUGIN_INFO_VALUE_DEF, inputCfg->is_Contrast,
  553.             PLUGIN_INFO_VALUE, (ULONG) "Contrast",                  /* GADGET */
  554.             AE_EndGroup,
  555.             AE_EndGroup,
  556.  
  557.             AE_Title("Clipping"),
  558.             PLUGIN_INFO_VALUE_MIN, 0,
  559.             PLUGIN_INFO_VALUE_MAX, maxW - inputCfg->is_Width,
  560.             PLUGIN_INFO_VALUE_DEF, inputCfg->is_XPos,
  561.             PLUGIN_INFO_VALUE, (ULONG) "X pos",                     /* GADGET */
  562.             PLUGIN_INFO_VALUE_MIN, 0,
  563.             PLUGIN_INFO_VALUE_MAX, maxH - inputCfg->is_Height,
  564.             PLUGIN_INFO_VALUE_DEF, inputCfg->is_YPos,
  565.             PLUGIN_INFO_VALUE, (ULONG) "Y pos",                     /* GADGET */
  566.             PLUGIN_INFO_VALUE_MIN, 4,
  567.             PLUGIN_INFO_VALUE_MAX, maxW - inputCfg->is_XPos,
  568.             PLUGIN_INFO_VALUE_DEF, inputCfg->is_Width,
  569.             PLUGIN_INFO_VALUE, (ULONG) "Width",                     /* GADGET */
  570.             PLUGIN_INFO_VALUE_MIN, 2,
  571.             PLUGIN_INFO_VALUE_MAX, maxH - inputCfg->is_YPos,
  572.             PLUGIN_INFO_VALUE_DEF, inputCfg->is_Height,
  573.             PLUGIN_INFO_VALUE, (ULONG) "Height",                    /* GADGET */
  574.  
  575.             TAG_MORE, (ULONG) (IsMonitoringAvailable(app->PubScreenName) ? monitoringTags : finalTags));
  576.     }
  577.  
  578.     return window;
  579. }
  580.  
  581.  
  582. /****** VLab/PlugIn_CloseWindow *********************************************
  583. *
  584. *   NAME
  585. *   PlugIn_CloseWindow -- Close the dialog window.
  586. *
  587. *   SYNOPSIS
  588. *   PlugIn_CloseWindow(app, window)
  589. *
  590. *   void PlugIn_CloseWindow(AE_AppObjPtr, AE_DialogPtr);
  591. *
  592. *   FUNCTION
  593. *   Close the dialog window opened by PlugIn_OpenWindow().
  594. *
  595. *   INPUTS
  596. *   app    - Application object obtained by AE_SetupPlugInTagList().
  597. *   window - Window pointer obtained by PlugIn_OpenWindow(). It's safe to
  598. *            pass a NULL pointer.
  599. *
  600. *   SEE ALSO
  601. *   PlugIn_OpenWindow(), AE_CloseWindow()
  602. *
  603. *****************************************************************************
  604. *
  605. */
  606.  
  607.  
  608. void PlugIn_CloseWindow(AE_AppObjPtr app, AE_DialogPtr window)
  609. {
  610.     if (window)
  611.         AE_CloseWindow(app, window);
  612. }
  613.  
  614.  
  615. /****** VLab/PlugIn_HandleGadget ********************************************
  616. *
  617. *   NAME
  618. *   PlugIn_HandleGadget -- Handle a gadget event.
  619. *
  620. *   SYNOPSIS
  621. *   monitoring = PlugIn_HandleGadget(app, window, event, monitoring)
  622. *
  623. *   struct VLabMonitor *PlugIn_HandleGadget(AE_AppObjPtr, AE_DialogPtr,
  624. *               AE_EventPtr, struct VLabMonitor *);
  625. *
  626. *   FUNCTION
  627. *   Handle a gadget event.
  628. *
  629. *   INPUTS
  630. *   app    - Application object obtained by AE_SetupPlugInTagList().
  631. *   window - Window pointer obtained by PlugIn_OpenWindow().
  632. *   event  - Event pointer :
  633. *       event->ID    : Gadget ID.
  634. *       event->Value : New gadget value.
  635. *
  636. *   RESULT
  637. *   monitoring - Pointer to a monitoring object.
  638. *   event->Error : Optional error code.
  639. *
  640. *   NOTES
  641. *   The HiRes and Lace flags are not sent to the vlab hardware, but the
  642. *   settings always reflect any changes made by the user. This means that
  643. *   the full set of flags must be sent to the hardware before grabbing a
  644. *   new picture.
  645. *   The "B&W source" gadget, when set, force any grab (as well as the
  646. *   monitoring) in greyscale mode.
  647. *
  648. *   SEE ALSO
  649. *
  650. *****************************************************************************
  651. *
  652. *   The "hires" and "lace" flags must not be sent to the vlab to avoid
  653. *   conflicts with the monitoring feature.
  654. *   Therefore, all flags sent to the VLab hardware by a call to the
  655. *   VLab_ChangeFlags function must be masked by MONITORING_MASK to avoid
  656. *   side effects. This allows the user to see the effect of the other flags
  657. *   while monitoring the current input.
  658. */
  659.  
  660.  
  661. struct VLabMonitor *PlugIn_HandleGadget(AE_AppObjPtr app, AE_DialogPtr window,
  662.                 AE_EventPtr event, struct VLabMonitor *monitoring)
  663. {
  664.     ULONG height, width, xScale, yScale;
  665.  
  666.     struct VLabSettings *settings = &CurSettings;
  667.     struct InputSettings *inputCfg = &settings->vs_Settings[settings->vs_Input];
  668.     LONG  value = event->Value;
  669.     ULONG flags = inputCfg->is_Flags;
  670.  
  671.     height = VLab_FrameHeight(inputCfg->is_VideoStd, flags);
  672.     width  = VLab_FrameWidth(flags);
  673.  
  674.     xScale = (flags & VLABF_HIRES) ? 4 : 2;
  675.     yScale = (flags & VLABF_LACE)  ? 2 : 1;
  676.  
  677.     /*
  678.     ** Handle all gadgets.
  679.     ** When a value concerning the image's dimensions is changed, the code takes care
  680.     ** to modify other related settings (xpos<->width and ypos<->height)
  681.     ** When the monitoring is active, some values need to be changed in real time so
  682.     ** that their effect applies to the monitoring as well.
  683.     */
  684.  
  685.     switch(event->ID) {
  686.  
  687.         /*
  688.         **              ########## Video ##########
  689.         */
  690.  
  691.         case GADID_INPUT:                       /* Input : CVBS1 / CVBS2 / SVHS */
  692.             settings->vs_Input = value;         /* Value : [0; 2]               */
  693.             inputCfg = &settings->vs_Settings[value];
  694.             updateGadgets(app, window, inputCfg);
  695.             VLab_ChangeInput(value);
  696.             break;
  697.  
  698.  
  699.         case GADID_VIDEO:                       /* PAL B/G/H/I, N, M, NTSC 4.43, M */
  700.             inputCfg->is_VideoStd = value;
  701.             VLab_ChangeVideo(value);
  702.             height = VLab_FrameHeight(value, flags);
  703.  
  704.             /*
  705.             ** Update YPos/Height gadgets.
  706.             ** When switching from PAL to NTSC, the current frame size
  707.             ** is scaled down to fit into the new limits.
  708.             */
  709.  
  710.             if (inputCfg->is_Height + inputCfg->is_YPos > height) {
  711.                 inputCfg->is_Height = (inputCfg->is_Height * 5) / 6;
  712.                 inputCfg->is_YPos   = (inputCfg->is_YPos   * 5) / 6;
  713.  
  714.                 if (flags & VLABF_LACE) {
  715.                     inputCfg->is_Height &= ~1;
  716.                     inputCfg->is_YPos   &= ~1;
  717.                 }
  718.             }
  719.  
  720.             AE_SetSlider(app, window, GADID_YPOS, inputCfg->is_YPos, 0, height - inputCfg->is_Height);
  721.             AE_SetSlider(app, window, GADID_HEIGHT, inputCfg->is_Height, yScale, height - inputCfg->is_YPos);
  722.  
  723.             /*
  724.             ** Resize the monitoring window. If this fails, the monitoring
  725.             ** is no longer active.
  726.             */
  727.  
  728.             if (monitoring) {
  729.                 value = settings->vs_Resolution;
  730.                 if (inputCfg->is_VideoStd >= VIDEO_525)
  731.                     value += MONITOR_SIZES;
  732.  
  733.                 monitoring = ResizeMonitor(monitoring, app->PubScreenName, value);
  734.             }
  735.             break;
  736.  
  737.  
  738.         case GADID_HUE:                         /* Hue (NTSC only) */
  739.             inputCfg->is_Hue = value;
  740.             VLab_ChangeHue(value);
  741.             break;
  742.  
  743.  
  744.         /*
  745.         **              ########## Filters ##########
  746.         */
  747.  
  748.         case GADID_VTR:                         /* Video Tape Recorder flag */
  749.             flags &= ~VLABF_VTR;
  750.             if (value)
  751.                 flags |= VLABF_VTR;
  752.             inputCfg->is_Flags = flags;
  753.             VLab_ChangeFlags(flags & MONITORING_MASK);
  754.             break;
  755.  
  756.  
  757.         case GADID_PREFILTER:                   /* Not checked : disabled */
  758.             flags &= ~VLABF_PREFILTER;
  759.             if (!value)
  760.                 flags |= VLABF_PREFILTER;
  761.             inputCfg->is_Flags = flags;
  762.             VLab_ChangeFlags(flags & MONITORING_MASK);
  763.             break;
  764.  
  765.  
  766.         case GADID_BW_SOURCE:                   /* Disable chroma filter */
  767.             flags &= ~VLABF_BW_SOURCE;
  768.             if (value)
  769.                 flags |= VLABF_BW_SOURCE;
  770.             inputCfg->is_Flags = flags;
  771.             VLab_ChangeFlags(flags & MONITORING_MASK);
  772.  
  773.             if (monitoring)
  774.                 MonitorChangeMode(monitoring, ((settings->vs_MonFlags & MONITOR_COLOR) && !value ? TRUE : FALSE));
  775.             break;
  776.  
  777.  
  778.         case GADID_BANDPASS:
  779.             inputCfg->is_Filters = FILTER_BANDPASS_W(inputCfg->is_Filters, value);
  780.             VLab_ChangeFilters(inputCfg->is_Filters);
  781.             break;
  782.  
  783.  
  784.         case GADID_CORING:
  785.             inputCfg->is_Filters = FILTER_CORING_W(inputCfg->is_Filters, value);
  786.             VLab_ChangeFilters(inputCfg->is_Filters);
  787.             break;
  788.  
  789.  
  790.         case GADID_WEIGHT:
  791.             inputCfg->is_Filters = FILTER_FACTOR_W(inputCfg->is_Filters, value);
  792.             VLab_ChangeFilters(inputCfg->is_Filters);
  793.             break;
  794.  
  795.  
  796.         /*
  797.         **              ########## Image ##########
  798.         */
  799.  
  800.         case GADID_GAMMA:                       /* Gamma correction */
  801.             inputCfg->is_Gamma = value;
  802.             VLab_LumaCorrection(inputCfg->is_Gamma, inputCfg->is_Brightness, inputCfg->is_Contrast);
  803.             break;
  804.  
  805.  
  806.         case GADID_BRIGHT:                      /* Brightness */
  807.             inputCfg->is_Brightness = value;
  808.             VLab_LumaCorrection(inputCfg->is_Gamma, inputCfg->is_Brightness, inputCfg->is_Contrast);
  809.             break;
  810.  
  811.  
  812.         case GADID_CONTRAST:                    /* Contrast */
  813.             inputCfg->is_Contrast = value;
  814.             VLab_LumaCorrection(inputCfg->is_Gamma, inputCfg->is_Brightness, inputCfg->is_Contrast);
  815.             break;
  816.  
  817.  
  818.         case GADID_LACE:                        /* Lace / No lace */
  819.             flags &= ~VLABF_LACE;
  820.             yScale = 1;
  821.             if (value) {
  822.                 flags |= VLABF_LACE;
  823.                 yScale = 2;
  824.             }
  825.  
  826.             inputCfg->is_Flags = flags;
  827.             height = VLab_FrameHeight(inputCfg->is_VideoStd, flags);
  828.  
  829.             /*
  830.             ** Update YPos/Height gadgets.
  831.             ** Both YPos/Height are scaled when they overflow the current
  832.             ** frame height or when the user switches to interlaced mode.
  833.             ** Otherwise, only the limits are changed.
  834.             */
  835.  
  836.             if (value) {
  837.                 inputCfg->is_YPos   *= 2;
  838.                 inputCfg->is_Height *= 2;
  839.             }
  840.             else {
  841.                 if (inputCfg->is_YPos + inputCfg->is_Height > height) {
  842.                     inputCfg->is_YPos   = inputCfg->is_YPos / 2;
  843.                     inputCfg->is_Height = inputCfg->is_Height / 2;
  844.                 }
  845.             }
  846.  
  847.             AE_SetSlider(app, window, GADID_YPOS, inputCfg->is_YPos, 0, height - inputCfg->is_Height);
  848.             AE_SetSlider(app, window, GADID_HEIGHT, inputCfg->is_Height, yScale, height - inputCfg->is_YPos);
  849.             /* AE bug ? In some case, the gadget value is not updated properly. */
  850.             /* This is the case when the new value exceeds the current limit.   */
  851.             AE_SetGadget(app, window, GADID_YPOS, inputCfg->is_YPos);
  852.             AE_SetGadget(app, window, GADID_HEIGHT, inputCfg->is_Height);
  853.             break;
  854.  
  855.  
  856.         case GADID_HIRES:
  857.             flags &= ~VLABF_HIRES;
  858.             xScale = 1;
  859.             if (value) {
  860.                 flags |= VLABF_HIRES;
  861.                 xScale = 2;
  862.             }
  863.  
  864.             inputCfg->is_Flags = flags;
  865.             width = VLab_FrameWidth(flags);
  866.  
  867.             /*
  868.             ** Update XPos/Width gadgets.
  869.             ** Both XPos/Width are scaled when they overflow the current
  870.             ** frame width or when the user switches to HiRes mode.
  871.             ** Otherwise, only the limits are changed.
  872.             */
  873.  
  874.             if (value) {
  875.                 inputCfg->is_XPos  *= 2;
  876.                 inputCfg->is_Width *= 2;
  877.             }
  878.             else {
  879.                 if (inputCfg->is_XPos + inputCfg->is_Width > width) {
  880.                     inputCfg->is_XPos  = (inputCfg->is_XPos / 2) & ~1;
  881.                     inputCfg->is_Width = (inputCfg->is_Width / 2) & ~1;
  882.                 }
  883.             }
  884.  
  885.             AE_SetSlider(app, window, GADID_XPOS, inputCfg->is_XPos, 0, width - inputCfg->is_Width);
  886.             AE_SetSlider(app, window, GADID_WIDTH, inputCfg->is_Width, xScale, width - inputCfg->is_XPos);
  887.             /* AE bug ? In some case, the gadget value is not updated properly. */
  888.             /* This is the case when the new value exceeds the current limit.   */
  889.             AE_SetGadget(app, window, GADID_XPOS, inputCfg->is_XPos);
  890.             AE_SetGadget(app, window, GADID_WIDTH, inputCfg->is_Width);
  891.             break;
  892.  
  893.  
  894.         case GADID_COLOR:
  895.             flags &= ~VLABF_COLOR;
  896.             if (value)
  897.                 flags |= VLABF_COLOR;
  898.             inputCfg->is_Flags = flags;
  899.             break;
  900.  
  901.  
  902.         /*
  903.         **              ########## Clipping ##########
  904.         **
  905.         **
  906.         ** The following values shall be rounded properly.
  907.         ** X, Width  : granule = 4 (HiRes) or 2 (LoRes)
  908.         ** Y, Height : granule = 1 (single frame) or 2 (interlaced mode)
  909.         ** Each time the user changes one setting, the maximum limit of
  910.         ** this setting's counter-part is modified (xpos<->width and
  911.         ** ypos<->height)
  912.         */
  913.  
  914.         case GADID_XPOS:
  915.             if (value > inputCfg->is_XPos)
  916.                 value += xScale - 1;
  917.  
  918.             value &= -xScale;
  919.             inputCfg->is_XPos = value;
  920.             AE_SetGadget(app, window, GADID_XPOS, value);
  921.             AE_SetSlider(app, window, GADID_WIDTH, inputCfg->is_Width, xScale, width - value);
  922.             break;
  923.  
  924.  
  925.         case GADID_YPOS:
  926.             if (value > inputCfg->is_YPos)
  927.                 value++;
  928.  
  929.             if (flags & VLABF_LACE)
  930.                 value &= -yScale;
  931.  
  932.             inputCfg->is_YPos = value;
  933.             AE_SetGadget(app, window, GADID_YPOS, value);
  934.             AE_SetSlider(app, window, GADID_HEIGHT, inputCfg->is_Height, yScale, height - value);
  935.             break;
  936.  
  937.  
  938.         case GADID_WIDTH:
  939.             if (value > inputCfg->is_Width)
  940.                 value += xScale - 1;
  941.  
  942.             value &= -xScale;
  943.             inputCfg->is_Width = value;
  944.             AE_SetGadget(app, window, GADID_WIDTH, value);
  945.             AE_SetSlider(app, window, GADID_XPOS, inputCfg->is_XPos, 0, width - value);
  946.             break;
  947.  
  948.  
  949.         case GADID_HEIGHT:
  950.             if (value > inputCfg->is_Height)
  951.                 value++;
  952.  
  953.             if (flags & VLABF_LACE)
  954.                 value &= -yScale;
  955.  
  956.             inputCfg->is_Height = value;
  957.             AE_SetGadget(app, window, GADID_HEIGHT, value);
  958.             AE_SetSlider(app, window, GADID_YPOS, inputCfg->is_YPos, 0, height - value);
  959.             break;
  960.  
  961.  
  962.         /*
  963.         **              ########## Monitoring ##########
  964.         */
  965.  
  966.         case GADID_COLORMONITOR:
  967.             flags = settings->vs_MonFlags & ~MONITOR_COLOR;
  968.             if (value)
  969.                 flags |= MONITOR_COLOR;
  970.  
  971.             settings->vs_MonFlags = flags;
  972.             set_monitoring_flags(settings);
  973.  
  974.             if (monitoring && !(inputCfg->is_Flags & VLABF_BW_SOURCE))
  975.                 MonitorChangeMode(monitoring, value);
  976.             break;
  977.  
  978.  
  979.         case GADID_DISABLE_PIP:
  980.             flags = settings->vs_MonFlags & ~MONITOR_NO_PIP;
  981.             if (value)
  982.                 flags |= MONITOR_NO_PIP;
  983.  
  984.             settings->vs_MonFlags = flags;
  985.             if (monitoring) {
  986.                 CloseMonitorWindow(monitoring);
  987.                 monitoring = open_monitor(app, event, settings);
  988.             }
  989.             break;
  990.  
  991.  
  992.         case GADID_RESOLUTION:
  993.             settings->vs_Resolution = value;
  994.  
  995.             if (inputCfg->is_VideoStd >= VIDEO_525)
  996.                 value += MONITOR_SIZES;
  997.  
  998.             /*
  999.             ** Resize the monitoring window. If this fails, the monitoring
  1000.             ** is no longer active.
  1001.             */
  1002.  
  1003.             if (monitoring)
  1004.                 monitoring = ResizeMonitor(monitoring, app->PubScreenName, value);
  1005.  
  1006.             break;
  1007.  
  1008.  
  1009.         case GADID_OPENMONITOR:
  1010.             if (!monitoring)
  1011.                 monitoring = open_monitor(app, event, settings);
  1012.             break;
  1013.  
  1014.  
  1015.         /*
  1016.         **              ########## RESET ##########
  1017.         */
  1018.  
  1019.         case GADID_RESET:
  1020.             /*
  1021.             ** Reset input specific settings to their last saved values.
  1022.             */
  1023.             settings->vs_Settings[settings->vs_Input] = SavedSettings.vs_Settings[settings->vs_Input];
  1024.             updateGadgets(app, window, inputCfg);
  1025.  
  1026.             /*
  1027.             ** Update vlab's internal state.
  1028.             */
  1029.  
  1030.             VLab_ChangeFilters(inputCfg->is_Filters);
  1031.             VLab_ChangeHue(inputCfg->is_Hue);
  1032.             VLab_ChangeFlags(inputCfg->is_Flags & MONITORING_MASK);
  1033.             VLab_ChangeVideo(value);
  1034.             VLab_LumaCorrection(inputCfg->is_Gamma, inputCfg->is_Brightness, inputCfg->is_Contrast);
  1035.  
  1036.             if (monitoring) {
  1037.                 MonitorChangeMode(monitoring, ((settings->vs_MonFlags & MONITOR_COLOR) &&
  1038.                                                     !(inputCfg->is_Flags & VLABF_BW_SOURCE) ? TRUE : FALSE));
  1039.             }
  1040.             break;
  1041.     }
  1042.  
  1043.     return monitoring;
  1044. }
  1045.  
  1046.  
  1047. /****i* VLab/updateGadgets **************************************************
  1048. *
  1049. *   NAME
  1050. *   updateGadgets -- Update gadgets related to input specific settings.
  1051. *
  1052. *   SYNOPSIS
  1053. *   updateGadgets(app, window, inputCfg)
  1054. *
  1055. *   static void updateGadgets(AE_AppObjPtr, AE_DialogPtr, struct InputSettings *);
  1056. *
  1057. *   FUNCTION
  1058. *   Update the gadgets that reflect input specific settings (image size and
  1059. *   dimension, filters, video mode, etc).
  1060. *
  1061. *   INPUTS
  1062. *   app      - Application object obtained by AE_SetupPlugInTagList().
  1063. *   window   - Window pointer obtained by PlugIn_OpenWindow().
  1064. *   inputCfg - Input specific settings.
  1065. *
  1066. *   SEE ALSO
  1067. *
  1068. *****************************************************************************
  1069. *
  1070. */
  1071.  
  1072.  
  1073. static void updateGadgets(AE_AppObjPtr app, AE_DialogPtr window, struct InputSettings *inputCfg)
  1074. {
  1075.     ULONG xScale, yScale, max_width, max_height;
  1076.     ULONG flags = inputCfg->is_Flags;
  1077.  
  1078.     AE_SetGadget(app, window, GADID_BANDPASS, FILTER_BANDPASS_R(inputCfg->is_Filters));
  1079.     AE_SetGadget(app, window, GADID_CORING, FILTER_CORING_R(inputCfg->is_Filters));
  1080.     AE_SetGadget(app, window, GADID_WEIGHT, FILTER_FACTOR_R(inputCfg->is_Filters));
  1081.     AE_SetGadget(app, window, GADID_VTR, ((flags & VLABF_VTR) ? 1 : 0));
  1082.     AE_SetGadget(app, window, GADID_PREFILTER, ((flags & VLABF_PREFILTER) ? 0 : 1));
  1083.     AE_SetGadget(app, window, GADID_BW_SOURCE, ((flags & VLABF_BW_SOURCE) ? 1 : 0));
  1084.  
  1085.     AE_SetGadget(app, window, GADID_HIRES, ((flags & VLABF_HIRES) ? 1 : 0));
  1086.     AE_SetGadget(app, window, GADID_LACE, ((flags & VLABF_LACE) ? 1 : 0));
  1087.     AE_SetGadget(app, window, GADID_COLOR, ((flags & VLABF_COLOR) ? 1 : 0));
  1088.     AE_SetGadget(app, window, GADID_GAMMA, inputCfg->is_Gamma);
  1089.     AE_SetGadget(app, window, GADID_BRIGHT, inputCfg->is_Brightness);
  1090.     AE_SetGadget(app, window, GADID_CONTRAST, inputCfg->is_Contrast);
  1091.     AE_SetGadget(app, window, GADID_HUE, inputCfg->is_Hue);
  1092.     AE_SetGadget(app, window, GADID_VIDEO, inputCfg->is_VideoStd);
  1093.  
  1094.     /*
  1095.     ** Update image dimension/position gadgets.
  1096.     */
  1097.  
  1098.     max_height = VLab_FrameHeight(inputCfg->is_VideoStd, flags);
  1099.     max_width  = VLab_FrameWidth(flags);
  1100.     xScale = (flags & VLABF_HIRES) ? 4 : 2;
  1101.     yScale = (flags & VLABF_LACE)  ? 2 : 1;
  1102.  
  1103.     AE_SetSlider(app, window, GADID_XPOS, inputCfg->is_XPos, 0, max_width - inputCfg->is_Width);
  1104.     AE_SetSlider(app, window, GADID_WIDTH, inputCfg->is_Width, xScale, max_width - inputCfg->is_XPos);
  1105.     AE_SetSlider(app, window, GADID_YPOS, inputCfg->is_YPos, 0, max_height - inputCfg->is_Height);
  1106.     AE_SetSlider(app, window, GADID_HEIGHT, inputCfg->is_Height, yScale, max_height - inputCfg->is_YPos);
  1107.  
  1108.     /* AE bug ? In some case, the gadget value is not updated properly. */
  1109.     /* This is the case when the new value exceeds the current limit.   */
  1110.  
  1111.     AE_SetGadget(app, window, GADID_XPOS, inputCfg->is_XPos);
  1112.     AE_SetGadget(app, window, GADID_WIDTH, inputCfg->is_Width);
  1113.     AE_SetGadget(app, window, GADID_YPOS, inputCfg->is_YPos);
  1114.     AE_SetGadget(app, window, GADID_HEIGHT, inputCfg->is_Height);
  1115. }
  1116.  
  1117.  
  1118. /****** VLab/PlugIn_Apply ***************************************************
  1119. *
  1120. *   NAME
  1121. *   PlugIn_Apply -- Apply the plug-in's effect
  1122. *
  1123. *   SYNOPSIS
  1124. *   PlugIn_Apply(app, event)
  1125. *
  1126. *   void PlugIn_Apply(AE_AppObjPtr, AE_EventPtr);
  1127. *
  1128. *   FUNCTION
  1129. *   Digitize a picture based on the current settings. A new paint window is
  1130. *   opened only if the operation succeeds.
  1131. *
  1132. *   INPUTS
  1133. *   app    - Application object obtained by AE_SetupPlugInTagList().
  1134. *   event  - Event pointer. event->Object points to the object the effect
  1135. *            shall be applied to.
  1136. *
  1137. *   RESULT
  1138. *   event->Error : Optional error code.
  1139. *
  1140. *   SEE ALSO
  1141. *
  1142. *****************************************************************************
  1143. *
  1144. *   The YUV buffer required by VLab_Grab() has been allocated when we opened
  1145. *   the window. Thus, the pointer remains valid even if the user digitizes
  1146. *   several pictures without closing the window.
  1147. *
  1148. *   The function reset all "flags" settings before processing. Some of those
  1149. *   flags cannot be changed when the user modify them because this collides
  1150. *   with the monitoring feature.
  1151. */
  1152.  
  1153.  
  1154. void PlugIn_Apply(AE_AppObjPtr app, AE_EventPtr event)
  1155. {
  1156.     struct InputSettings *inputCfg = &CurSettings.vs_Settings[CurSettings.vs_Input];
  1157.     long errCode = PLUGIN_ERROR_MEMORY;     /* Default : No memory error */
  1158.     AE_ObjPtr Picture;                      /* Current Picture object to grab to. */
  1159.  
  1160.     /*
  1161.     ** Allocate a new picture object (we'll display the new image there)
  1162.     ** then create an access cache for this object.
  1163.     */
  1164.  
  1165.     if ( (Picture = AE_AllocPicture(app, inputCfg->is_Width, inputCfg->is_Height,
  1166.                 ((inputCfg->is_Flags & VLABF_COLOR) ? PIC_RGB : PIC_GRAYSCALE))) ) {
  1167.  
  1168.         int  vlabErr, colorFlag;
  1169.         ULONG mode, line;
  1170.  
  1171.         /*
  1172.         ** The monitoring activity uses different settings. Make sure we use
  1173.         ** the right ones for the final shot.
  1174.         */
  1175.         VLab_ChangeFlags(inputCfg->is_Flags);
  1176.         mode = (inputCfg->is_Flags & VLABF_HIRES) ? CAPTURE_HIRES : CAPTURE_LORES;
  1177.         colorFlag = ((inputCfg->is_Flags & (VLABF_COLOR | VLABF_BW_SOURCE)) == VLABF_COLOR);
  1178.  
  1179.         AE_BeginOperation(app, Picture, "Digitizing...");
  1180.         if (VLab_InitHardware())
  1181.             vlabErr = VLABERR_I2C;
  1182.         else
  1183.             vlabErr = VLab_Grab(inputCfg->is_XPos, inputCfg->is_YPos, inputCfg->is_Width, inputCfg->is_Height,
  1184.                             mode, colorFlag);
  1185.  
  1186.         /*
  1187.         ** Fill-in the picture object. In greyscale mode, the Luma component is
  1188.         ** used as is.
  1189.         */
  1190.  
  1191.         if (vlabErr == VLABERR_OK) {
  1192.             UBYTE *buffer;
  1193.             ULONG step;
  1194.             ULONG colorMode;
  1195.  
  1196.             if (colorFlag) {
  1197.                 buffer = RGB_Buffer;
  1198.                 step = inputCfg->is_Width * 3;
  1199.                 colorMode = BITMAP_TYPE_RGB;
  1200.                 VLab_YUV_to_RGB(buffer, inputCfg->is_Width * inputCfg->is_Height,
  1201.                         ((inputCfg->is_Flags & VLABF_HIRES) ? CAPTURE_HIRES : CAPTURE_LORES));
  1202.             }
  1203.             else {
  1204.                 buffer = VLab_GetYBuffer();
  1205.                 step = inputCfg->is_Width;
  1206.                 colorMode = BITMAP_TYPE_GRAY8;
  1207.             }
  1208.  
  1209.             /*
  1210.             ** ArtEffect bitmap is filled line by line (there's no way to copy
  1211.             ** the image in one go).
  1212.             */
  1213.  
  1214.             for (line = 0; line < inputCfg->is_Height; line++, buffer += step)
  1215.                 AE_WriteHLine(app, Picture, buffer, 0, line, inputCfg->is_Width, colorMode);
  1216.         }
  1217.  
  1218.         AE_EndOperation(app, Picture);
  1219.  
  1220.         if (vlabErr == VLABERR_OK) {
  1221.             AE_SetPicture(app, Picture);
  1222.             errCode = PLUGIN_ERROR_NONE;
  1223.         }
  1224.         else {
  1225.             const char *text;
  1226.  
  1227.             AE_FreePicture(app, Picture);
  1228.             errCode = PLUGIN_ERROR_CUSTOM;
  1229.             text = VLab_GetErrorString(vlabErr);
  1230.             AE_DoRequestTags(app, AER_TYPE_INFO, AER_BodyText, (ULONG) text, AER_TitleText, (ULONG) "VLab error", TAG_DONE);
  1231.         }
  1232.     }
  1233.  
  1234.     event->Error = errCode;
  1235. }
  1236.  
  1237.  
  1238. /****i* VLab/set_monitoring_flags *******************************************
  1239. *
  1240. *   NAME
  1241. *   set_monitoring_flags -- Set monitoring specific flags
  1242. *
  1243. *   SYNOPSIS
  1244. *   set_monitoring_flags(settings)
  1245. *
  1246. *   void set_monitoring_flags(struct VLabSettings *);
  1247. *
  1248. *   FUNCTION
  1249. *   Initialize the VLab hardware for LoRes non-lace scanning.
  1250. *
  1251. *   INPUTS
  1252. *   settings - Pointer to the actual settings.
  1253. *
  1254. *   SEE ALSO
  1255. *
  1256. *****************************************************************************
  1257. *
  1258. */
  1259.  
  1260.  
  1261. static void set_monitoring_flags(struct VLabSettings *settings)
  1262. {
  1263.     ULONG flags = settings->vs_Settings[settings->vs_Input].is_Flags & MONITORING_MASK;
  1264.  
  1265.     VLab_ChangeFlags(flags);
  1266. }
  1267.  
  1268.  
  1269. /****i* VLab/open_monitor ***************************************************
  1270. *
  1271. *   NAME
  1272. *   open_monitor -- Open the monitoring window
  1273. *
  1274. *   SYNOPSIS
  1275. *   monitorHandle = open_monitor(app, event, settings)
  1276. *
  1277. *   struct VLabMonitor *open_monitor(AE_AppObjPtr, AE_EventPtr,
  1278. *                               struct VLabSettings *);
  1279. *
  1280. *   FUNCTION
  1281. *   Open the monitoring window, which is either a standard window or a PiP
  1282. *   layer.
  1283. *
  1284. *   INPUTS
  1285. *   app      - Application object pointer.
  1286. *   event    - Event pointer.
  1287. *   settings - Pointer to the current settings.
  1288. *
  1289. *   RESULT
  1290. *   monitorHandle - Pointer to a private Monitor structure, or NULL if the
  1291. *           monitoring is not available for some reason. If the monitoring
  1292. *           fails, the function displays an error requester and set the
  1293. *           event's error code to PLUGIN_ERROR_CUSTOM.
  1294. *
  1295. *   SEE ALSO
  1296. *
  1297. *****************************************************************************
  1298. *
  1299. */
  1300.  
  1301.  
  1302. static struct VLabMonitor *open_monitor(AE_AppObjPtr app, AE_EventPtr event, struct VLabSettings *settings)
  1303. {
  1304.     struct VLabMonitor *monitor;
  1305.     ULONG resolution = settings->vs_Resolution;
  1306.     ULONG monFlags = settings->vs_MonFlags;
  1307.  
  1308.     if (settings->vs_Settings[settings->vs_Input].is_VideoStd >= VIDEO_525)
  1309.         resolution += MONITOR_SIZES;
  1310.  
  1311.     /*
  1312.     ** Setup monitoring settings.
  1313.     */
  1314.  
  1315.     if (settings->vs_Settings[settings->vs_Input].is_Flags & VLABF_BW_SOURCE)
  1316.         monFlags &= ~MONITOR_COLOR;
  1317.  
  1318.     if ( (monitor = OpenMonitorWindow(app->PubScreenName, settings->vs_WLeft, settings->vs_WTop,
  1319.                         resolution, monFlags)) ) {
  1320.         set_monitoring_flags(settings);
  1321.     }
  1322.     else if (event) {
  1323.         event->Error = PLUGIN_ERROR_CUSTOM;
  1324.         AE_DoRequestTags(app, AER_TYPE_INFO, AER_BodyText, (ULONG) "Monitoring not available.", (ULONG) "GUI error", TAG_DONE);
  1325.     }
  1326.  
  1327.     return monitor;
  1328. }
  1329.  
  1330.